package cn.example.vip.mall.permission.init;

import cn.example.vip.mall.permission.entity.Permission;
import cn.example.vip.mall.permission.service.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Springboot实现初始化权限数据的方式:
 * 1.实现ApplicationRunner接口
 * 2.实现CommandLineRunner接口
 */
@Component
public class InitPermission implements ApplicationRunner {
	
	@Autowired
	private PermissionService permissionService;
	@Autowired
	private RedisTemplate redisTemplate;
	
	
	/**
	 * 权限初始化:
	 * 1.所有权限初始化:需要校验的接口地址
	 * 2.角色权限初始化:用户访问权限
	 * @param args
	 * @throws Exception
	 */
	@Override
	public void run(ApplicationArguments args) throws Exception {
		updateRolePermission();
	}
	
	
	/**
	 * 从数据更新角色权限
	 */
	public void updateRolePermission() {
		// 1. 0:完全匹配过滤,1:通配符匹配过滤/{path}
		List<Permission> permissionMatch0 = permissionService.findByMatch(0);
		List<Permission> permissionMatch1 = permissionService.findByMatch(1);
		// 所有角色的权限: 查询角色权限映射关系
		List<Map<Integer, Integer>> rolePermissions = permissionService.allRolePermission();
		// 匹配每个角色拥有的权限列表
		Map<String, Set<Permission>> roleMap = rolePermissionFilter(rolePermissions, permissionMatch0, permissionMatch1);
		// 存储到Redis缓存
		// 数据
		redisTemplate.boundHashOps("RolePermissionAll").put("PermissionMatch0", permissionMatch0);
		redisTemplate.boundHashOps("RolePermissionAll").put("PermissionMatch1", permissionMatch1);
		// 角色权限
		redisTemplate.boundHashOps("RolePermissionMap").putAll(roleMap);
	}
	
	
	/**
	 * 查询每个角色拥有的权限
	 * @param rolePermissions
	 */
	public Map<String, Set<Permission>> rolePermissionFilter(List<Map<Integer, Integer>> rolePermissions,
									 List<Permission> permissionMatch0,
									 List<Permission> permissionMatch1) {
		// 每个角色拥有的权限查询 存入Map
		// Match 0 Match 1
		Map<String, Set<Permission>> rolePermissionMap = new HashMap<>();
		
		// 循环查询角色关系映射
		for(Map<Integer, Integer> rolePermission : rolePermissions) {
			// 角色ID
			Integer rid = rolePermission.get("rid");
			// 权限ID
			Integer pid = rolePermission.get("pid");
			
			// 定义Redis-Key:
			// 完全匹配
			String key0 = "Role_0_" + rid;
			// 通配符匹配
			String key1 = "Role_1_" + rid;
			// 获取当前角色的权限列表
			/*Set<Permission> permissionSet0 = rolePermissionMap.get(key0);
			Set<Permission> permissionSet1 = rolePermissionMap.get(key1);
			if(permissionSet0 == null){
				permissionSet0 = new HashSet<Permission>();
			}
			if(permissionSet1 == null){
				permissionSet1 = new HashSet<Permission>();
			}*/
			Set<Permission> permissionSet0 = rolePermissionMap.getOrDefault(key0, new HashSet<>());
			Set<Permission> permissionSet1 = rolePermissionMap.getOrDefault(key1, new HashSet<>());
			
			// 查询每个角色对应的权限-完全匹配
			for(Permission permission : permissionMatch0) {
				if(permission.getId().intValue() == pid.intValue() ) {
					// 权限匹配完成
					permissionSet0.add(permission);
					break;
				}
			}
			
			// 通配符匹配
			for(Permission permission : permissionMatch1) {
				if(permission.getId().intValue() == pid.intValue() ) {
					// 权限匹配完成
					permissionSet1.add(permission);
					break;
				}
			}
			
			// 存储权限映射
			if(permissionMatch0.size() > 0) {
				rolePermissionMap.put(key0, permissionSet0);
			}
			if(permissionMatch1.size() > 0){
				rolePermissionMap.put(key1, permissionSet1);
			}
			
		}
		
		return rolePermissionMap;
		
	}
	
}
